package com.java.zhuiyun.api.SysUser.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java.zhuiyun.api.sysmenu.entity.Menu;
import com.java.zhuiyun.api.sysmenu.service.IMenuService;
import com.java.zhuiyun.api.sysrole.mapper.RoleMapper;
import com.java.zhuiyun.api.sysrolemenu.mapper.RoleMenuMapper;
import com.java.zhuiyun.api.SysUser.common.Constants;
import com.java.zhuiyun.api.SysUser.controller.dto.UserDTO;
import com.java.zhuiyun.api.SysUser.entity.Password;
import com.java.zhuiyun.api.SysUser.entity.SysUser;
import com.java.zhuiyun.api.SysUser.mapper.SysUserMapper;
import com.java.zhuiyun.api.SysUser.service.ISysUserService;
import com.java.zhuiyun.common.response.CommonResult;
import com.java.zhuiyun.exception.ServiceException;
import com.java.zhuiyun.util.Md5Utils;
import com.java.zhuiyun.util.TokenUtils;
import com.java.zhuiyun.util.UploadFileUtils;
import com.java.zhuiyun.util.pageUtil.MybatisPageHelper;
import com.java.zhuiyun.util.pageUtil.PageRequest;
import com.java.zhuiyun.util.pageUtil.PageResult;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @ClassName SysUserServiceimpl
 * @Description TODO
 * @Author 星宇
 * @Date 2023/8/14 19:55
 **/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    private static final Log LOG = Log.get();

    @Resource
    SysUserMapper sysUserMapper;

    @Resource
    RoleMapper roleMapper;

    @Resource
    IMenuService menuService;

    @Resource
    RoleMenuMapper roleMenuMapper;

    /**
    * @Author xy
    * @Description 全查
    * @Date 2023/8/15 18:49
    * @Return  * @param null
    */
    @Override
    public PageResult userList(SysUser sysUser, PageRequest pageRequest) {
        MybatisPageHelper.startPage(pageRequest);
        PageResult pageResult = MybatisPageHelper.getPageResult(sysUserMapper.userList(sysUser));
        return pageResult;
    }

    /**
    * @Author xy
    * @Description 添加
    * @Date 2023/8/16 19:45
    * @Return  * @param null
    */
    @Override
    public int SysUserAdd(SysUser sysUser,MultipartFile file) {
        if(file==null){
            return 0;
        }
        String s = UploadFileUtils.uploadFile(file);
        if(s.equals("")){
            return 0;
        }
        // 获取当前时间
        Date date = new Date();
        // 添加时间时获取当前时间
        sysUser.setCreateTime(date);
        // 添加时字段del_flag默认为0
        sysUser.setDelFlag(0);
        // 设置默认密码为 "123456"
        String password = "123456";
        // 对密码进行 MD5 加密
        String md5Password = Md5Utils.getMd5(password);
        sysUser.setPassword(md5Password);
        sysUser.setAvatarUrl(s);
        return sysUserMapper.SysUserAdd(sysUser);
    }

    /**
    * @Author xy
    * @Description 修改
    * @Date 2023/8/16 19:45
    * @Return  * @param null
    */
    @Override
    public int SysUserUpdate(SysUser sysUser,MultipartFile file) {
        if(file!=null){
            String s = UploadFileUtils.uploadFile(file);
            if(s.equals("")){
                return 0;
            }
            sysUser.setAvatarUrl(s);
        }

        // 获取当前时间
        Date date = new Date();
        // 获取当前修改时间
        sysUser.setUpdateTime(date);


        return sysUserMapper.SysUserupdate(sysUser);
    }

    /**
    * @Author xy
    * @Description 设置禁用状态
    * @Date 2023/9/2 11:22
    * @Return  * @param null
    */
    @Override
    public int updatescope(SysUser sysUser) {
        // 设置禁用状态
        return sysUserMapper.updatescope(sysUser);
    }

    /**
    * @Author xy
    * @Description 逻辑删除
    * @Date 2023/8/16 19:45
    * @Return  * @param null
    */
    @Override
    public int SysUserDelete(Integer id) {
        return sysUserMapper.SysUserDelete(id);
    }

    @Override
    public UserDTO login(UserDTO userDTO) {
        // 根据用户名查询用户信息
        SysUser one = getUserInfo(userDTO);
        if (one != null) {
            // 判断用户是否被禁用
            if ("1".equals(one.getIsDisable())) {
                throw new ServiceException(Constants.CODE_601, "用户已被禁用，无法登录");
            }

            BeanUtil.copyProperties(one, userDTO, true);
            // 设置token
            String token = TokenUtils.genToken(one.getId().toString(), one.getPassword());
            userDTO.setToken(token);

            //ROLE_ADMIN
            String role = one.getRole();
            // 设置用户的菜单列表
            List<Menu> roleMenus = getRoleMenus(role);
            userDTO.setMenus(roleMenus);
            return userDTO;
        } else {
            throw new ServiceException(Constants.CODE_600, "用户名或密码错误");
        }
    }

    private String getMD5Hash(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();

            for (byte b : messageDigest) {
                hexString.append(String.format("%02x", b));
            }

            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException("MD5 hashing failed", e);
        }
    }

    private SysUser getUserInfo(UserDTO userDTO){
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        // selet * frrm user where user_name = userDTO.getUserName()  admin
        queryWrapper.eq("user_name",userDTO.getUserName());
        queryWrapper.eq("password",getMD5Hash(userDTO.getPassword()));
        SysUser one;
        try {
            //从数据库查询用户信息
            one = getOne(queryWrapper);
        } catch (Exception e) {
            throw new ServiceException(Constants.CODE_500,"系统错误");
        }
        return one;
    }

    /**
    * @Author xy
    * @Description 获取当前角色的菜单列表
    * @Date 2023/8/22 10:16
    * @Return  * @param null
    */
    private List<Menu> getRoleMenus(String roleFlag) {
        Integer roleId = roleMapper.selectByFlag(roleFlag);
        // 根据角色id查询菜单id集合
        List<Integer> menuIds = roleMenuMapper.selectByRoleId(roleId);
        // 查出系统所有的菜单(树形)
        List<Menu> menus = menuService.findMenus("");
        // new一个最后筛选完成之后的list
        List<Menu> roleMenus = new ArrayList<>();
        // 筛选当前用户角色的菜单
        for (Menu menu : menus) {
            if (menuIds.contains(menu.getId())) {
                // 如果当前菜单不在当前角色的菜单id集合中,则跳过
                roleMenus.add(menu);
            }
            // removeIf()  移除 children 里面不在 menuIds集合中的 元素
            List<Menu> children = menu.getChildren();
            children.removeIf(child -> !menuIds.contains(child.getId()));
        }
        return roleMenus;
    }

    /**
    * @Author 杨友朋
    * @Description TODO 修改个人信息
    * @Date 2023/8/22 14:38
    * @Return
    * @param
    */
    @Override
    public CommonResult saveInfo(SysUser sysUser) {
        if(sysUser.getId()!=null&&sysUser.getId()!=0){
            sysUser.setUpdateTime(new Date());
            Integer i=sysUserMapper.updateInfo(sysUser);
            if(i>0){
                return CommonResult.ok();
            }
        }
        return CommonResult.error(500,"更改信息失败");
    }

    @Override
    public CommonResult savePassword(Password password) {
        if(password.getId()==null||password.getId()==0){
            return CommonResult.error(500,"修改密码失败,未检测到账户id!!!");
        }
        SysUser sysUser = sysUserMapper.selectById(password.getId());
        if(sysUser.getPassword().equals(password.getOldPassword())){
            Integer i=sysUserMapper.savePassword(password);
            if(i>0){
                return CommonResult.ok("保存成功");
            }
            return CommonResult.error(500,"系统繁忙,请稍后再试!!!");
        }
        return CommonResult.error(500,"旧密码不正确!!!");
    }

}
